package com.z.redis.command.impl.string;

import com.z.redis.RedisCore;
import com.z.redis.command.CommandType;
import com.z.redis.command.WriteCommand;
import com.z.redis.datatype.BytesWrapper;
import com.z.redis.datatype.RedisData;
import com.z.redis.datatype.RedisString;
import com.z.redis.resp.BulkString;
import com.z.redis.resp.Resp;
import com.z.redis.resp.SimpleString;
import com.z.redis.util.Format;
import io.netty.channel.ChannelHandlerContext;

import static java.nio.charset.StandardCharsets.UTF_8;


/**
 * 对String类型的数据 而且是整数类型的 进行-1的操作
 */
public class Decr implements WriteCommand {
    private BytesWrapper key;
    @Override
    public CommandType type(){
        return CommandType.decr;
    }

    @Override
    public void setContent(Resp[] array){
        key = ((BulkString)array[1]).getContent(); // 解析键名
    }

    @Override
    public void handle(ChannelHandlerContext ctx, RedisCore redisCore){
        RedisData redisData = redisCore.get(key);
        if(redisData == null){
            BytesWrapper bytesWrapper = new BytesWrapper("0".getBytes(UTF_8));
            RedisString stringData = new RedisString();
            try {
                long v = Format.parseLong(bytesWrapper.getByteArray(), 10); // 字节数组转化成长整型数值 10进制
                v--;
                bytesWrapper = new BytesWrapper(Format.toByteArray(v));
                stringData.setValue(bytesWrapper);
                redisCore.put(key,stringData); // 存储新键值对
                ctx.writeAndFlush(new BulkString(bytesWrapper)); // 返回结果
            } catch (NumberFormatException exception){
                ctx.writeAndFlush(new SimpleString("value is not an integer or out of range"));
            }
        }else if(redisData instanceof RedisString){
            try {
                BytesWrapper value = ((RedisString) redisData).getValue();
                long v = Format.parseLong(value.getByteArray(), 10); // 字节数组转化成长整型数值 10进制
                v--;
                BytesWrapper bytesWrapper = new BytesWrapper(Format.toByteArray(v));
                ((RedisString)redisData).setValue(bytesWrapper);
                redisCore.put(key,redisData); // 更新键值对
                ctx.writeAndFlush(new BulkString(bytesWrapper)); // 返回结果
            }catch (NumberFormatException exception){
                ctx.writeAndFlush(new SimpleString("value is not an integer or out of range"));
            }
        }else {
            throw new UnsupportedOperationException();
        }
    }

    /**
     * 无网络响应
     * @param redisCore
     */
    @Override
    public void handle(RedisCore redisCore){
        RedisData redisData = redisCore.get(key);
        if(redisData == null){ // 键不存在
            try {
                RedisString stringData = new RedisString(new BytesWrapper("0".getBytes(UTF_8)));
                BytesWrapper value = stringData.getValue();
                long v = Format.parseLong(value.getByteArray(), 10); // 字节数组转化成长整型数值 10进制
                v++;
                stringData.setValue(new BytesWrapper(Format.toByteArray(v)));
                redisCore.put(key,stringData);
            }catch (NumberFormatException exception){
                // 静默忽略错误
            }
        }else if(redisData instanceof RedisString){
            try {
                BytesWrapper value = ((RedisString) redisData).getValue();
                long v = Format.parseLong(value.getByteArray(), 10); // 字节数组转化成长整型数值 10进制
                v--;
                ((RedisString) redisData).setValue(new BytesWrapper(Format.toByteArray(v)));
            }catch (NumberFormatException exception){
                // 静默忽略错误
            }
        }else {
            throw new UnsupportedOperationException();
        }
    }
}
